﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Interfaces;
using Medianamik.Core.Synchronization;
using Medianamik.Globalization;
using Medianamik.UI.Lock;
using Telerik.Web.UI;
using Medianamik.Core.Configuration;
using System.Configuration;
using System.Globalization;
using Medianamik.Core.Profile;
using Medianamik.Core.Sugar;

namespace Medianamik.UI.Controls
{
    [ParseChildren(true)]
    public class MedianamikFormTemplate : WebControl, INamingContainer
    {
        private const string MultiPageID = "E3511774-4F0B-47e7-9F83-5A23583BEA82";
        private const string TabStripID = "E59E8918-2ABF-49e6-9F27-F2BD34E39D48";
        private const string PageViewID = "53E07DC7-5A41-43f0-A695-74C73CFF0064";
        private const string DefaultGroupName = "DefaultGroupName";
        private static readonly MedianamikConfigSection Config = (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);
        private const string MedianamikLookupTemplateModeEditForm = "EditForm";
        private const string GridPlaceHolderPrefix = "phGrid_";
        private const string EditFormPlaceHolderPrefix = "phEdit_";
        protected const string ActionColumnUniqueName = "SubActionColumn";
        private const string SubGridValidationSummary = "subgridvalidationsummary";
        private const string AddButtonPrefix = "add_";
        private const string SaveButtonPrefix = "save_";
        private const string CancelButtonPrefix = "cancel_";

        public string Mode
        {
            get
            {
                return ViewState["Mode2"] == null ? MedianamikLookupTemplateModeEditForm :
                    ViewState["Mode2"].ToString();
            }
            set { ViewState["Mode2"] = value; }
        }

        private MasterPage _myMasterPage;
        public MasterPage MyMasterPage
        {
            get
            {
                if (_myMasterPage == null && Page.Master != null)
                {
                    _myMasterPage = Page.Master;

                    while (_myMasterPage.Master != null)
                    {
                        _myMasterPage = _myMasterPage.Master;
                    }
                }

                return _myMasterPage;
            }
        }

        private ITemplate _template;
        private RadTabStrip _tabStrip;
        private RadMultiPage _multiPage;
        private ValidationSummary _valSummary;
        private LockActivator _lockActivator;
        public LockActivator LockActivator
        {
            get { return _lockActivator ?? (_lockActivator = new LockActivator()); }
        }
        private LockRequester _lockRequester;
        public LockRequester LockRequester
        {
            get { return _lockRequester ?? (_lockRequester = new LockRequester()); }
        }

        readonly BaseModalWindow _propertyPreviewWindow = new BaseModalWindow();

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            var radWindowManager = MyMasterPage.FindControl("radWindowManager") as RadWindowManager;

            if (radWindowManager != null && radWindowManager.Windows.Cast<Control>().FirstOrDefault(w => w.ID == "PropertyPreviewWindow") == null)
            {
                _propertyPreviewWindow.IconUrl = "/Medianamik/images/Icones/Ico_Visualisation.gif";
                _propertyPreviewWindow.ReloadOnShow = true;
                _propertyPreviewWindow.Width = Unit.Pixel(640);
                _propertyPreviewWindow.Height = Unit.Pixel(480);
                _propertyPreviewWindow.ID = "PropertyPreviewWindow";
                radWindowManager.Windows.Add(_propertyPreviewWindow);
            }
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();
            CreateControlHierarchy(!IsDataBound);
        }

        public RadMultiPage MultiPage
        {
            get
            {
                return _multiPage;
            }
        }

        public RadTabStrip TabStrip
        {
            get
            {
                return _tabStrip;
            }
        }

        protected int? MedianamikControlCount
        {
            get
            {
                return ((int?)ViewState["MedianamikControlCount"]).GetValueOrDefault();
            }
            set
            {
                ViewState["MedianamikControlCount"] = value;
            }
        }

        protected string[] MedianamikControlTypes
        {
            get
            {
                return ViewState["MedianamikControlTypes"] as string[];
            }
            set
            {
                ViewState["MedianamikControlTypes"] = value;
            }
        }

        protected int? GroupCount
        {
            get
            {
                return ((int?)ViewState["GroupCount"]).GetValueOrDefault();
            }
            set
            {
                ViewState["GroupCount"] = value;
            }
        }
        protected string[] MedianamikControlGroups
        {
            get { return ViewState["MedianamikControlGroups"] as string[]; }
            set { ViewState["MedianamikControlGroups"] = value; }
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

        public Guid NodeId
        {
            get
            {
                return (Guid?)ViewState["NodeId"]
                       ?? (Guid)(ViewState["NodeId"] = Guid.NewGuid());
            }
            set
            {
                ViewState["NodeId"] = value;
            }
        }

        protected Guid TypeId
        {
            get
            {
                return (Guid)ViewState["TypeId"];
            }
            set
            {
                ViewState["TypeId"] = value;
            }
        }

        protected Guid? ParentId
        {
            get
            {
                return (Guid?)ViewState["ParentId"];
            }
            set
            {
                ViewState["ParentId"] = value;
            }
        }

        [PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(MedianamikFormTemplateContainer))]
        public ITemplate Template
        {
            get
            {
                return _template;
            }
            set
            {
                _template = value;
            }
        }

        [Browsable(false)]
        public virtual object DataSource
        {
            get
            {
                return _dataSource;
            }
            set
            {
                // make sure we're working with a Node
                var node = value as Node;
                if (node == null)
                {
                    throw new ArgumentException("DataSource must be assigned a Node.");
                }

                _dataSource = node;
            }
        }
        private object _dataSource;

        private Node GetDataSource()
        {
            return DataSource as Node;
        }

        public T GetFormValue<T>(T currentNode) where T : INodeWrapper
        {
            GetFormValue(currentNode.InnerNode);

            return currentNode;
        }

        public Node GetFormValue(Node currentNode)
        {
            EnsureChildControls();

            //var node = NodeManager.GetNode<T>(NodeId);
            var node = currentNode;

            if (node == null)
                //node = NodeManager.NewNode<T>(TypeId, CultureInfo.GetCultureInfo(DefaultCultureName), this.ParentId);
                throw new ArgumentNullException("currentNode");

            if (Template == null)
            {
                var mkControls = _multiPage.Controls.OfType<RadPageView>()
                    .SelectMany(p => p.Controls.Cast<Control>()).OfType<IMedianamikControl>();

                var cultureNames = new HashSet<string>();
                mkControls.ForEach(c => cultureNames.Add(c.EditionCultureName));
                node.AddNodeInstances(cultureNames);

                foreach (var mkControl in mkControls)
                {
                    NodeProperty prop;

                    if (mkControl.EditionCultureName == "" && !node.Instances.Exists(""))
                    {
                        var control = mkControl;
                        prop = node.Instances[0].Properties
                            .FirstOrDefault(p => p.NodeTypePropertyID
                                                     .Equals(control.NodeTypePropertyId));
                    }
                    else
                    {
                        var control = mkControl;
                        prop = node.Instances[mkControl.EditionCultureName]
                            .Properties.FirstOrDefault(p => p.NodeTypePropertyID
                                                                .Equals(control.NodeTypePropertyId));
                    }

                    if (prop != null)
                    {
                        prop.SetValue(mkControl.GetValue());
                    }

                    if (mkControl.IsMultiLingual)
                    {
                        foreach (var cult in mkControl.GetCultureTargets())
                        {
                            var control = mkControl;
                            var propInstance =
                                node.Instances[cult.CultureName].Properties.FirstOrDefault(
                                    p => p.NodeTypePropertyID.Equals(control.NodeTypePropertyId));
                            if (propInstance != null)
                                propInstance.SetValue(mkControl.GetValue());
                        }
                    }
                }

            }
            else
            {
                UpdateNode(Container, node);
            }

            return node;
        }

        public bool EnableLocking
        {
            get
            {
                return (bool?)ViewState["EnableLocking"] ?? true;
            }
            set { ViewState["EnableLocking"] = value; }
        }

        public bool HideLegend
        {
            get
            {
                return (bool?)ViewState["HideLegend"] ?? false;
            }
            set { ViewState["HideLegend"] = value; }
        }

        public bool HideNeutralLanguageIndication
        {
            get
            {
                return (bool?)ViewState["HideNeutralLanguageIndication"] ?? default(bool);
            }
            set { ViewState["HideNeutralLanguageIndication"] = value; }
        }

        public bool HideValidationSummary
        {
            get
            {
                return (bool?)ViewState["ValidationSummary"] ?? false;
            }
            set { ViewState["ValidationSummary"] = value; }
        }

        protected bool IsDataBound
        {
            get
            {
                return ((bool?)ViewState["IsDataBound"]).GetValueOrDefault();
            }
            set { ViewState["IsDataBound"] = value; }
        }

        public bool AutoGenerateValidators
        {
            get
            {
                object o = ViewState["AutoGenerateValidators"];
                if (o == null)
                {
                    return true;
                }
                return (bool)o;
            }
            set { ViewState["AutoGenerateValidators"] = value; }
        }

        public CultureInfo EditionCulture
        {
            get
            {
                var result = ViewState["EditionCulture"] as CultureInfo;

                if (result == null)
                    throw new Exception("MedianamikFormTemplate's EditionCulture property is mandatory.");

                return result;
            }
            set { ViewState["EditionCulture"] = value; }
        }

        public string RadMultiPageId
        {
            get
            {
                var result = ViewState["RadMultiPageId"];

                if (result != null && result.ToString() != String.Empty)
                    return result.ToString();

                return null;
            }
            set { ViewState["RadMultiPageId"] = value; }
        }

        public string RadTabStripId
        {
            get
            {
                var result = ViewState["RadTabStripId"];

                if (result != null && result.ToString() != String.Empty)
                    return result.ToString();

                return null;
            }
            set { ViewState["RadTabStripId"] = value; }
        }

        public bool EnableClientScriptValidation
        {
            get
            {
                object o = ViewState["EnableClientScriptValidation"];
                if (o == null)
                {
                    return false;
                }
                return (bool)o;
            }
            set { ViewState["EnableClientScriptValidation"] = value; }
        }

        public Control Container
        {
            get
            {
                return _container;
            }
        }
        private Control _container;

        protected string[] PropertyIds
        {
            get
            {
                if (_propertyIds == null && ViewState["PropertyIds"] != null)
                {
                    _propertyIds = (string[])ViewState["PropertyIds"];
                }
                return _propertyIds;
            }
            set
            {
                _propertyIds = value;
                ViewState["PropertyIds"] = _propertyIds;
            }
        }
        string[] _propertyIds = null;

        protected Dictionary<string, string[]> LookupMedianamikControlTypes
        {
            get
            {
                return ViewState["LookupMedianamikControlTypes"] as Dictionary<string, string[]>;
            }
            set
            {
                ViewState["LookupMedianamikControlTypes"] = value;
            }
        }

        protected Dictionary<string, string[]> LookupPropertyIds
        {
            get
            {
                return ViewState["LookupPropertyIds"] as Dictionary<string, string[]>;
            }
            set
            {
                ViewState["LookupPropertyIds"] = value;
            }
        }

        public string HiddenProperties
        {
            get
            {
                return ViewState["HiddenProperties"] == null ? string.Empty :
                    ViewState["HiddenProperties"].ToString();
            }
            set { ViewState["HiddenProperties"] = value; }
        }

        public string OverriddenPropertiesControls
        {
            get
            {
                return ViewState["OverriddenPropertiesControls"] == null ? string.Empty :
                    ViewState["OverriddenPropertiesControls"].ToString();
            }
            set { ViewState["OverriddenPropertiesControls"] = value; }
        }

        private string _validationGroup = BaseMedianamikControl.DefaultValidationGroupName;
        public string ValidationGroup
        {
            get { return _validationGroup; }
            set { _validationGroup = value; }
        }

        private Dictionary<Guid, Guid> _allOverriddenPropertiesControls;
        protected Dictionary<Guid, Guid> AllOverriddenPropertiesControls
        {
            get
            {
                return _allOverriddenPropertiesControls ??
                       (_allOverriddenPropertiesControls = BuildOverriddenPropertiesControls());
            }
        }

        private Dictionary<Guid, Guid> BuildOverriddenPropertiesControls()
        {
            var dict = new Dictionary<Guid, Guid>();

            if (!String.IsNullOrEmpty(OverriddenPropertiesControls))
            {
                var entries = OverriddenPropertiesControls.Split(';');

                foreach (var entry in entries)
                {
                    var propertyIdAndControlId = entry.Split('|');

                    Guid propertyId;
                    Guid controlId;

                    if (propertyIdAndControlId.Count() == 2 &&
                        StringHelper.IsGuid(propertyIdAndControlId.First(), out propertyId) &&
                        StringHelper.IsGuid(propertyIdAndControlId.ElementAt(1), out controlId))
                    {
                        dict.Add(propertyId, controlId);
                    }
                }
            }

            return dict;
        }

        public string SaveButtonClientId
        {
            get
            {
                return (string)ViewState["SaveButtonClientId"] ?? "";
            }
            set { ViewState["SaveButtonClientId"] = value; }
        }

        public DateTime? Revision
        {
            get{return ViewState["Revision"] as DateTime?;}
            set { ViewState["Revision"] = value; }
        }

        public CultureInfo DuplicateCulture
        {
            get
            {
                return Config.EnableMultiLanguageFeatures &&
                    ((UserProfile)HttpContext.Current.Profile).EnableMultiLanguageFeatures ?
                    ViewState["DuplicateCulture"] as CultureInfo : null;
            }
            set { ViewState["DuplicateCulture"] = value; }
        }

        public override Control FindControl(string id)
        {
            EnsureChildControls();
            var control = base.FindControl(id);

            if (control == null && Container != null)
            {
                //Chercher le control dans le FormTemplateContainer
                control = Container.FindControl(id);
            }

            return control;
        }

        public override void DataBind()
        {
            base.OnDataBinding(EventArgs.Empty);

            // Create the control hierarchy.  First, clear out the child controls
            Controls.Clear();
            ClearChildViewState();
            TrackViewState();

            // Create the control hierarchy
            CreateControlHierarchy(true);

            // Mark the hierarchy as having been created
            ChildControlsCreated = true;
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (SaveButtonClientId.Length > 0)
            {
                writer.Write("<script type=\"text/javascript\">\n");
                writer.Write(String.Format("$(function() {{$('#{0}').defaultButton('#{1}');}});",
                    ClientID, SaveButtonClientId));

                writer.Write("</script>\n");
            }

            base.Render(writer);
        }

        private void CreateControlHierarchy(bool useDataSource)
        {
            if (AutoGenerateValidators && !HideValidationSummary)
            {
                AddValidators(this, ValidationGroup);
            }

            var dataSource = GetDataSource();

            if (useDataSource)
            {
                IsDataBound = true;

                if (DuplicateCulture != null)
                {
                    if (dataSource.Instances.Exists(EditionCulture))
                        throw new ApplicationException(
                            "L'instance à créée ne doit pas exister lors de la duplication d'une langue.");

                    if (!dataSource.Instances.Exists(DuplicateCulture))
                        throw new ApplicationException(
                            "L'instance à dupliquée doit exister lors de la duplication d'une langue.");
                }

                NodeId = dataSource.ID;
                TypeId = dataSource.NodeTypeID;
                ParentId = dataSource.ParentID;
            }

            if (EnableLocking)
            {
                SetupLock(useDataSource, dataSource);
            }

            if (Template == null)
            {
                CreateControlHierarchyForNonTemplated(useDataSource, dataSource);
            }
            else
            {
                //Il peut y avoir plusieurs instances gérées simultanément
                CreateControlHierarchyForTemplated(useDataSource);
            }
        }

        private void CreateControlHierarchyForTemplated(bool useDataSource)
        {
            _container = new MedianamikFormTemplateContainer();
            Controls.Add(_container);
            Template.InstantiateIn(_container);

            if (useDataSource)
            {
                _container.DataBind();
            }

            if (EnableClientScriptValidation && ContainsDisabledClientScriptValidator(_container))
            {
                _valSummary.EnableClientScript = false;
                DisableClientSideValidation(_container);
            }

            if (!HideLegend)
                Controls.Add(new Caption());
        }

        private void CreateControlHierarchyForNonTemplated(bool useDataSource, Node dataSource)
        {
            List<NodeProperty> props;
            List<string> groups;

            var medianamikLookups = Parent.FindControlsR<MedianamikLookup>();

            if (useDataSource)
            {
                if (dataSource.IsLanguageNeutral && EditionCulture.Name != String.Empty)
                    throw new ApplicationException(
                        "MedianamikFormTemplate Error: Language neutral node edited in non language neutral page.");

                if (!dataSource.IsLanguageNeutral && EditionCulture.Name == String.Empty)
                    throw new ApplicationException(
                        "MedianamikFormTemplate Error: Non language neutral node edited in language neutral page.");

                var instance = dataSource.Instances.Exists(EditionCulture)
                                   ? dataSource.Instances[EditionCulture]
                                   : dataSource.AddNodeInstance(EditionCulture.Name);

                if (DuplicateCulture != null)
                {
                    var copiedInstance = dataSource.Instances[DuplicateCulture];
                    foreach (var prop in copiedInstance.Properties)
                    {
                        instance[prop.NodeTypePropertyID].SetValue(prop.Value);
                    }
                }

                props = instance.GetPropertiesForRevision(Revision)
                    .Where(p => p.MedianamikControl != null
                                && MedianamikContext.Current.MedianamikUser
                                       .CanAccessProperty(p.NodeTypeProperty) &&
                                       instance.Node.NodeType.PropertyIsVisible(p.NodeTypeProperty.ID) &&
                                       !HiddenProperties.Split(',').Any(pr => p.NodeTypeProperty.Name.Equals(pr.TrimStart().TrimEnd(), StringComparison.OrdinalIgnoreCase)))
                    .OrderBy(p => p.Position).ToList();

                if (DuplicateCulture != null)
                {
                    var urlProp = props.SingleOrDefault(p => p.NodeTypeProperty.IsUrl);

                    if (urlProp != null)
                        urlProp.SetValue(null);
                }

                if (dataSource.NodeTypeID.Equals(MedianamikTypes.MedianamikSyndication))
                {
                    props.Remove(props.Single(p => p.NodeTypePropertyID
                                                       .Equals(MedianamikProperties.Name)));

                    props.Remove(props.Single(p => p.NodeTypePropertyID
                                                       .Equals(MedianamikProperties.UseInChildUrls)));
                }

                groups = props.GroupBy(p => p.GroupName.ToLower()).Select(g => g.Key).ToList();

                //Ajout pour les medianamikLookup 03-12-2009
                if (medianamikLookups != null && medianamikLookups.Count() > 0)
                {
                    foreach (var lookup in medianamikLookups)
                    {
                        string tabName = lookup.TabName;
                        if (!groups.Exists(g => g == tabName))
                            groups.Add(tabName);
                    }
                }
            }
            else
            {
                props = new NodeProperty[MedianamikControlCount.Value].ToList();
                groups = new string[GroupCount.Value].ToList();
            }

            if (props.Count() > 0)
            {
                //Ajouter RadTabStrip et RadMultiPage si non fourni
                SetRadControls();

                if (useDataSource)
                {
                    CreateTabs(groups);
                }

                var propertyIds = new List<string>();
                var tempMedianamikControlTypes = new List<string>();

                for (var i = 0; i < props.Count; i++)
                {
                    var prop = props.ElementAt(i);

                    if (useDataSource)
                    {
                        var groupName = string.IsNullOrEmpty(prop.GroupName.ToLower()) ? DefaultGroupName : prop.GroupName.ToLower();
                        var pageView = _multiPage.FindPageViewByID(String.Concat(PageViewID, "_", groupName.ToLower()));

                        IMedianamikControl mkControl;
                        Guid controlId;

                        if (AllOverriddenPropertiesControls.TryGetValue(prop.NodeTypeProperty.ID, out controlId))
                        {
                            mkControl = prop.GetMedianamikControl(EnableClientScriptValidation,
                                AutoGenerateValidators, groupName, controlId);
                        }
                        else
                        {
                            mkControl = prop.GetMedianamikControl(EnableClientScriptValidation,
                                AutoGenerateValidators, groupName);
                        }

                        var control = mkControl.Control;
                        pageView.Controls.Add(control);
                        control.ID = prop.NodeTypePropertyID.ToString("N");
                        propertyIds.Add(control.ID);

                        if (mkControl.DataSource != null)
                        {
                            control.DataBind();
                        }

                        tempMedianamikControlTypes.Add(control.GetType().AssemblyQualifiedName);
                    }
                    else
                    {
                        var groupName = string.IsNullOrEmpty(MedianamikControlGroups[i]) ? DefaultGroupName : MedianamikControlGroups[i];
                        var pageView = _multiPage.FindPageViewByID(String.Concat(PageViewID, "_", groupName.ToLower()));
                        var control = new ObjectBuilder(MedianamikControlTypes[i]).GetInstance<IMedianamikControl>().Control;
                        control.ID = PropertyIds[i]; //Important - cette ligne avant la suivante
                        pageView.Controls.Add(control);
                    }
                }

                if (useDataSource)
                {
                    //Ajout pour les medianamikLookup 03-12-2009
                    if (medianamikLookups != null && medianamikLookups.Count() > 0)
                    {
                        var lookupPropertyIds = new Dictionary<string, string[]>();
                        var medianamikControlTypes = new Dictionary<string, string[]>();

                        for (var i = 0; i < medianamikLookups.Count(); i++)
                        {
                            var lookup = medianamikLookups.ElementAt(i);

                            var tabName = string.IsNullOrEmpty(lookup.TabName.ToLower()) ? DefaultGroupName : lookup.TabName.ToLower();
                            var lookupPageView = _multiPage.FindPageViewByID(String.Concat(PageViewID, "_", tabName.ToLower()));
                            //var mkControl = prop.GetMedianamikControl(EnableClientScriptValidation, AutoGenerateValidators);

                            var editPlaceHolder = new PlaceHolder { ID = EditFormPlaceHolderPrefix + lookup.TypeName }; //Placeholder pour le mode d edition
                            lookupPageView.Controls.Add(editPlaceHolder);
                            editPlaceHolder.Visible = false;

                            AddValidators(editPlaceHolder, SubGridValidationSummary);

                            var gridPlaceHolder = new PlaceHolder { ID = GridPlaceHolderPrefix + lookup.TypeName }; //Placeholder pour le mode grille
                            lookupPageView.Controls.Add(gridPlaceHolder);
                            gridPlaceHolder.Visible = true;

                            var medianamikLookupProperties = BuildLookupEditForm(lookup, true, editPlaceHolder, lookup.TypeName);

                            lookupPropertyIds[lookup.TypeName] = medianamikLookupProperties.PropertyIds;
                            medianamikControlTypes[lookup.TypeName] = medianamikLookupProperties.MedianamikControlTypes;

                            gridPlaceHolder.Controls.Add(new LiteralControl("<p>"));

                            var addButton = new Button { ID = AddButtonPrefix + lookup.TypeName };
                            gridPlaceHolder.Controls.Add(addButton);
                            addButton.Text = String.IsNullOrEmpty(lookup.AddButtonText) ?
                                Translator.Translate("Medianamik_Global", "Add") : lookup.AddButtonText;
                            addButton.CssClass = "Btn";
                            addButton.Click += AddButtonClick;
                            addButton.CausesValidation = false;

                            gridPlaceHolder.Controls.Add(new LiteralControl("</p>"));

                            gridPlaceHolder.Controls.Add(new LiteralControl("<br />"));

                            var saveButton = new Button();
                            saveButton.ID = SaveButtonPrefix + lookup.TypeName;
                            editPlaceHolder.Controls.Add(saveButton);
                            saveButton.Text = Translator.Translate("medianamik_global", "SaveButtonText");
                            saveButton.CssClass = "Btn";
                            saveButton.ValidationGroup = SubGridValidationSummary;
                            saveButton.CausesValidation = true;

                            saveButton.Click += SaveButtonClick;

                            editPlaceHolder.Controls.Add(new LiteralControl("&nbsp;"));

                            var cancelButton = new Button();
                            cancelButton.ID = CancelButtonPrefix + lookup.TypeName;
                            editPlaceHolder.Controls.Add(cancelButton);
                            cancelButton.Text = Translator.Translate("medianamik_global", "Cancel");
                            cancelButton.CausesValidation = false;
                            cancelButton.CssClass = "Btn";
                            cancelButton.Click += CancelButtonClick;

                            var grid = new RadGrid();

                            //Setup de la grille
                            grid.MasterTableView.DataKeyNames = new[] { "Id" };
                            grid.ItemCommand += GridItemCommand;
                            //grid.DataSource = lookup.GetRecordsForGrid();
                            grid.NeedDataSource += SubgridNeedDataSource;
                            grid.EnableEmbeddedSkins = false;
                            grid.Skin = "Medianamik";
                            grid.Width = Unit.Percentage(100);

                            if (lookup.Columns.Count() > 0)
                            {
                                foreach (var column in lookup.Columns)
                                {
                                    var customColumn = new GridTemplateColumn
                                    {
                                        HeaderText = column.HeaderText,
                                        UniqueName = Guid.NewGuid().ToString("N"),
                                        ItemTemplate = new SubGridColumnTemplate(column.Name),
                                        SortExpression = column.Name
                                    };

                                    grid.MasterTableView.Columns.Add(customColumn);
                                }
                            }
                            else
                            {
                                var customColumn = new GridTemplateColumn
                                {
                                    HeaderText = Translator.Translate("Medianamik_ContentManagement",
                                    "ContentNameColumn"),
                                    UniqueName = Guid.NewGuid().ToString("N"),
                                    ItemTemplate = new SubGridColumnTemplate("Name"),
                                    SortExpression = "Name"
                                };

                                grid.MasterTableView.Columns.Add(customColumn);
                            }
                            grid.MasterTableView.AllowCustomSorting = true;
                            if (lookup.AllowLinesReordering)
                            {
                                grid.SortCommand += subgrid_SortCommand;
                                grid.ClientSettings.AllowRowsDragDrop = true;
                                grid.ClientSettings.EnableRowHoverStyle = true;
                                grid.ClientSettings.Selecting.AllowRowSelect = true;
                                grid.RowDrop += RowDrop;
                                grid.ClientSettings.Selecting.EnableDragToSelectRows = true;
                                grid.Columns[0].ItemStyle.CssClass = "DragCursor";
                            }

                            grid.AllowSorting = lookup.AllowOrderByColumn;
                            grid.AllowPaging = false;
                            grid.AutoGenerateColumns = false;


                            var actionColumn = new GridTemplateColumn
                            {
                                HeaderText = "Actions",
                                UniqueName = ActionColumnUniqueName,
                                ItemTemplate = new SubGridActionColumnTemplate(OnEditSubItem,
                                    OnDeleteSubItem)
                            };

                            grid.MasterTableView.Columns.Add(actionColumn);

                            actionColumn.ItemStyle.CssClass = "Actions";
                            actionColumn.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
                            actionColumn.HeaderStyle.Width = Unit.Percentage(1);
                            grid.MasterTableView.EnableColumnsViewState = false;

                            grid.ID = lookup.TypeName;
                            subGridLookup.Add(grid.ID, lookup);
                            gridPlaceHolder.Controls.Add(grid);
                            grid.DataBind();
                        }

                        SetLookupViewstate(lookupPropertyIds, medianamikControlTypes);
                    }

                    SetViewstate(props, groups, propertyIds, tempMedianamikControlTypes);
                }
                else
                {
                    //Ajout pour le medianamikLookup - 03-12-2009
                    if (medianamikLookups != null && medianamikLookups.Count() > 0)
                    {
                        foreach (var lookup in medianamikLookups)
                        {
                            var tabName = lookup.TabName.ToLower();
                            var lookupPageView =
                                _multiPage.FindPageViewByID(String.Concat(PageViewID, "_", tabName.ToLower()));
                            //var mkControl = prop.GetMedianamikControl(EnableClientScriptValidation, AutoGenerateValidators);

                            var editPlaceHolder = new PlaceHolder(); //Placeholder pour le mode d edition
                            editPlaceHolder.ID = EditFormPlaceHolderPrefix + lookup.TypeName;
                            var gridPlaceHolder = new PlaceHolder(); //Placeholder pour le mode grille
                            gridPlaceHolder.ID = GridPlaceHolderPrefix + lookup.TypeName;

                            lookupPageView.Controls.Add(editPlaceHolder);

                            AddValidators(editPlaceHolder, SubGridValidationSummary);

                            lookupPageView.Controls.Add(gridPlaceHolder);

                            BuildLookupEditForm(lookup, false, editPlaceHolder, lookup.TypeName);

                            gridPlaceHolder.Controls.Add(new LiteralControl("<p>"));

                            var addButton = new Button { ID = AddButtonPrefix + lookup.TypeName };
                            gridPlaceHolder.Controls.Add(addButton);
                            addButton.Text = String.IsNullOrEmpty(lookup.AddButtonText) ?
                                Translator.Translate("Medianamik_Global", "Add") : lookup.AddButtonText;
                            addButton.CssClass = "Btn";
                            addButton.Click += AddButtonClick;
                            addButton.CausesValidation = false;

                            gridPlaceHolder.Controls.Add(new LiteralControl("</p>"));

                            gridPlaceHolder.Controls.Add(new LiteralControl("<br />"));

                            var saveButton = new Button { ID = SaveButtonPrefix + lookup.TypeName };
                            editPlaceHolder.Controls.Add(saveButton);
                            saveButton.Text = Translator.Translate("medianamik_global", "SaveButtonText");
                            saveButton.CssClass = "Btn";
                            saveButton.ValidationGroup = SubGridValidationSummary;
                            saveButton.CausesValidation = true;

                            saveButton.Click += SaveButtonClick;

                            editPlaceHolder.Controls.Add(new LiteralControl("&nbsp;"));

                            var cancelButton = new Button { ID = CancelButtonPrefix + lookup.TypeName };
                            editPlaceHolder.Controls.Add(cancelButton);
                            cancelButton.Text = Translator.Translate("medianamik_global", "Cancel");
                            cancelButton.CausesValidation = false;
                            cancelButton.CssClass = "Btn";
                            cancelButton.Click += CancelButtonClick;

                            var grid = new RadGrid();

                            //Setup de la grille
                            grid.MasterTableView.DataKeyNames = new[] { "Id" };
                            grid.ItemCommand += GridItemCommand;
                            //grid.DataSource = lookup.GetRecordsForGrid(grid.MasterTableView.SortExpressions.GetSortString());
                            grid.NeedDataSource += SubgridNeedDataSource;
                            grid.EnableEmbeddedSkins = false;
                            grid.Skin = "Medianamik";
                            grid.Width = Unit.Percentage(100);

                            if (lookup.Columns.Count() > 0)
                            {
                                foreach (var column in lookup.Columns)
                                {
                                    var customColumn = new GridTemplateColumn
                                    {
                                        HeaderText = column.HeaderText,
                                        UniqueName = Guid.NewGuid().ToString("N"),
                                        ItemTemplate = new SubGridColumnTemplate(column.Name),
                                        SortExpression = column.Name
                                    };

                                    grid.MasterTableView.Columns.Add(customColumn);
                                }
                            }
                            else
                            {
                                var customColumn = new GridTemplateColumn
                                {
                                    HeaderText = Translator.Translate("Medianamik_ContentManagement",
                                    "ContentNameColumn"),
                                    UniqueName = Guid.NewGuid().ToString("N"),
                                    ItemTemplate = new SubGridColumnTemplate("Name"),
                                    SortExpression = "Name"
                                };

                                grid.MasterTableView.Columns.Add(customColumn);
                            }
                            grid.MasterTableView.AllowCustomSorting = true;
                            if (lookup.AllowLinesReordering)
                            {
                                grid.SortCommand += subgrid_SortCommand;
                                grid.ClientSettings.AllowRowsDragDrop = true;
                                grid.ClientSettings.EnableRowHoverStyle = true;
                                grid.ClientSettings.Selecting.AllowRowSelect = true;
                                grid.RowDrop += RowDrop;
                                grid.ClientSettings.Selecting.EnableDragToSelectRows = true;
                                grid.Columns[0].ItemStyle.CssClass = "DragCursor";
                            }

                            grid.AllowSorting = lookup.AllowOrderByColumn;
                            grid.AllowPaging = false;
                            grid.AutoGenerateColumns = false;

                            var actionColumn = new GridTemplateColumn
                            {
                                HeaderText = "Actions",
                                UniqueName = ActionColumnUniqueName,
                                ItemTemplate = new SubGridActionColumnTemplate(OnEditSubItem,
                                    OnDeleteSubItem)
                            };

                            grid.MasterTableView.Columns.Add(actionColumn);

                            actionColumn.ItemStyle.CssClass = "Actions";
                            actionColumn.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
                            actionColumn.HeaderStyle.Width = Unit.Percentage(1);
                            grid.MasterTableView.EnableColumnsViewState = false;

                            grid.ID = lookup.TypeName;
                            subGridLookup.Add(grid.ID, lookup);
                            //grid.DataSource = lookup.GetRecordsForGrid(grid.MasterTableView.SortExpressions.GetSortString());
                            gridPlaceHolder.Controls.Add(grid);
                        }
                    }
                }

                if (EnableClientScriptValidation && ContainsDisabledClientScriptValidator(_multiPage))
                {
                    _valSummary.EnableClientScript = false;
                    DisableClientSideValidation(_multiPage);
                }
            }

            if (!HideLegend)
                Controls.Add(new Caption());
        }

        Dictionary<string, MedianamikLookup> subGridLookup = new Dictionary<string, MedianamikLookup>();

        private void SubgridNeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
            RadGrid grid = (RadGrid)source;
            BindSubGridDataSouce(grid);
        }

        private void BindSubGridDataSouce(RadGrid subGrid)
        {
            var lookup = subGridLookup[subGrid.ID];
            if (subGrid.MasterTableView.SortExpressions.Count > 0)
            {
                subGrid.DataSource = lookup.GetRecordsForGrid(subGrid.MasterTableView.SortExpressions[0].FieldName, subGrid.MasterTableView.SortExpressions[0].SortOrder == GridSortOrder.Ascending);
            }
            else
            {
                subGrid.DataSource = lookup.GetRecordsForGrid();
            }
        }

        private void subgrid_SortCommand(object source, GridSortCommandEventArgs e)
        {
            RadGrid subGrid = (RadGrid)source;
            GridSortExpression sortExpr = new GridSortExpression();
            sortExpr.FieldName = e.SortExpression;
            switch (e.OldSortOrder)
            {
                case GridSortOrder.None:
                    sortExpr.SortOrder = GridSortOrder.Ascending;
                    break;
                case GridSortOrder.Ascending:
                    sortExpr.SortOrder = GridSortOrder.Descending;
                    break;
                case GridSortOrder.Descending:
                    sortExpr.SortOrder = subGrid.MasterTableView.AllowNaturalSort ? GridSortOrder.None : GridSortOrder.Ascending;
                    break;
            }
            e.Item.OwnerTableView.SortExpressions.AddSortExpression(sortExpr);
            e.Canceled = true;
            //BindSubGridDataSouce(subGrid);
            subGrid.Rebind();
        }

        void RowDrop(object sender, GridDragDropEventArgs e)
        {
            var grid = sender as RadGrid;

            if (grid != null && e.DraggedItems[0].OwnerGridID == grid.ClientID &&
                String.IsNullOrEmpty(e.HtmlElement))
            {
                var lookupName = grid.ID;

                var currentLookup = GetCurrentLookup(lookupName);
                var records = currentLookup.DataSource.ToList();
                var movedNodeId = (Guid)e.DraggedItems[0].GetDataKeyValue("Id");
                var destinationNodeId = (Guid)e.DestDataItem.GetDataKeyValue("Id");
                var position = e.DropPosition == GridItemDropPosition.Above
                                ? DropPosition.Above
                                : DropPosition.Below;
                currentLookup.DataSource = ChangeNodeOrder(records, movedNodeId, destinationNodeId,
                                                  position).ToArray();
                grid.DataSource = currentLookup.GetRecordsForGrid();
                grid.DataBind();
            }
        }

        public static Collection<Record> ChangeNodeOrder(List<Record> siblings,
            Guid movedNodeId, Guid? pDestinationNodeId, DropPosition pPosition)
        {
            if (siblings.Count < 2)
            {
                //Pas d'ordonancement à faire.
                return new Collection<Record>(siblings);
            }

            //Ordonner les Noeuds par position
            siblings.Sort(Record.ComparePosition);

            var movedNode = siblings.First(n => n.Id == movedNodeId);

            //Retirer le noeud de la collection
            siblings.Remove(movedNode);

            //Si destinationNodeId n'a pas de valeur, le noeud ira en première position
            var destinationNodeId = pDestinationNodeId ?? siblings[0].Id.Value;

            //Trouver le noeud situé avant
            int position = 0;

            if (siblings.Exists(n => n.Id == pDestinationNodeId))
            {
                position = siblings.FindIndex(n => n.Id == destinationNodeId) + (int)pPosition;
            }

            //Insertion du Noeud à la bonne position
            siblings.Insert(position, movedNode);

            //Mettre à jour la position
            for (short i = 0; i < siblings.Count; i++)
            {
                var currentNode = siblings[i];

                if (currentNode.Position != i)
                {
                    currentNode.Position = i;
                }
            }

            return new Collection<Record>(siblings);
        }

        protected virtual void OnEditSubItem(object sender, CommandEventArgs e)
        {
            Guid nodeId;
            if (e.CommandArgument != null && StringHelper.IsGuid(e.CommandArgument.ToString(), out nodeId))
            {
                var grid = (RadGrid)((Control)sender).Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
                var lookupName = grid.ID;

                var currentLookup = GetCurrentLookup(lookupName);
                var records = currentLookup.DataSource.ToList();
                var record = records.First(r => r.Id.Equals(nodeId));
                //grid.DataSource = currentLookup.GetRecordsForGrid();
                //grid.DataBind();
                var editForm = GetPlaceHolder(lookupName, EditFormPlaceHolderPrefix);
                var saveButton = (Button)editForm.FindControl(SaveButtonPrefix + lookupName);
                saveButton.CommandArgument = nodeId.ToString();
                FillEditForm(record, currentLookup);
                SwitchMode(lookupName, false);
            }
        }

        protected virtual void OnDeleteSubItem(object sender, CommandEventArgs e)
        {
            Guid nodeId;
            if (e.CommandArgument != null && StringHelper.IsGuid(e.CommandArgument.ToString(), out nodeId))
            {
                var grid = (RadGrid)((Control)sender).Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent;
                var lookupName = grid.ID;

                var currentLookup = GetCurrentLookup(lookupName);
                var records = currentLookup.DataSource.ToList();
                var record = records.First(r => r.Id.Equals(nodeId));
                records.Remove(record);

                record.SynchronizeAction = SynchronizeActions.Delete;
                currentLookup.DataSource = records.Union(new[] { record }).ToArray();
                grid.DataSource = currentLookup.GetRecordsForGrid();
                grid.DataBind();
            }
        }

        private void SetLookupViewstate(Dictionary<string, string[]> lookupPropertyIds,
            Dictionary<string, string[]> medianamikControlTypes)
        {
            LookupPropertyIds = lookupPropertyIds;
            LookupMedianamikControlTypes = medianamikControlTypes;
        }

        private MedianamikLookupProperties BuildLookupEditForm(MedianamikLookup lookup,
            bool useDataSource, PlaceHolder placeHolder, string lookupTypeName)
        {
            var nodeType = NodeTypeManager.GetNodeType(lookup.TypeName);

            var props = nodeType.GetAllProperties()
                .Where(p => p.MedianamikControl != null
                            && MedianamikContext.Current.MedianamikUser
                                   .CanAccessProperty(p) &&
                                   nodeType.PropertyIsVisible(p.ID) &&
                            !lookup.HiddenProperties.Split(',').Any(pr => p.Name.Equals(pr.TrimStart().TrimEnd(), StringComparison.OrdinalIgnoreCase)))
                .OrderBy(p => nodeType.GetPropertyPosition(p.ID)).ToList();

            var propertyIds = new List<string>();

            for (var i = 0; i < props.Count; i++)
            {
                var prop = props.ElementAt(i);

                if (useDataSource)
                {
                    var mkControl = prop.GetMedianamikControl(EnableClientScriptValidation,
                        EditionCulture, SubGridValidationSummary, HideNeutralLanguageIndication);
                    var control = mkControl.Control;
                    placeHolder.Controls.Add(control);
                    control.ID = lookupTypeName + "_" + prop.Name;
                    propertyIds.Add(control.ID);
                    control.DataBind();
                }
                else
                {
                    var control = new ObjectBuilder(LookupMedianamikControlTypes[lookupTypeName][i])
                        .GetInstance<IMedianamikControl>().Control;
                    control.ID = LookupPropertyIds[lookupTypeName][i]; //Important - cette ligne avant la suivante
                    placeHolder.Controls.Add(control);
                }
            }

            return new MedianamikLookupProperties(propertyIds.ToArray(),
                props.Select(p => p.MedianamikControl.FullName).ToArray());
        }

        void AddButtonClick(object sender, EventArgs e)
        {
            //Il faudrait peut-etre vider les controles d editions pour etre sur de n avoir aucune valeur a l ajout
            string lookupName = ((Button)sender).ID.Replace(AddButtonPrefix, "");
            var editForm = GetPlaceHolder(lookupName, EditFormPlaceHolderPrefix);
            var lookupIds = LookupPropertyIds[lookupName];

            foreach (var lookupControlId in lookupIds)
            {
                var propertyName = lookupControlId.Replace(lookupName + "_", "");
                BaseMedianamikControl control = ((BaseMedianamikControl)editForm.FindControl(lookupControlId));
                if (control.TypeOfValue.IsGenericType && control.TypeOfValue.GetGenericTypeDefinition() == typeof(Nullable<>))
                    ((BaseMedianamikControl)editForm.FindControl(lookupControlId)).SetValue(null);
                else
                    ((BaseMedianamikControl)editForm.FindControl(lookupControlId))
                        .SetValue("");
            }
            var saveButton = (Button)editForm.FindControl(SaveButtonPrefix + lookupName);
            saveButton.CommandArgument = Guid.Empty.ToString();

            SwitchMode(lookupName, false);
        }

        void CancelButtonClick(object sender, EventArgs e)
        {
            string lookupName = ((Button)sender).ID.Replace(CancelButtonPrefix, "");
            SwitchMode(lookupName, true);
        }

        void SaveButtonClick(object sender, EventArgs e)
        {
            Page.Validate(SubGridValidationSummary);

            if (Page.IsValid)
            {
                var lookupName = ((Button)sender).ID.Replace(SaveButtonPrefix, "");
                var editForm = GetPlaceHolder(lookupName, EditFormPlaceHolderPrefix);
                var lookupIds = LookupPropertyIds[lookupName];
                var currentLookup = GetCurrentLookup(lookupName);
                var recordId = new Guid(((Button)sender).CommandArgument);
                var gridSource = currentLookup.DataSource.ToList();

                if (recordId == Guid.Empty)
                {
                    var newRecord = new Record
                                        {
                                            NodeTypeName = lookupName,
                                            DefaultCultureName = EditionCulture.Name,
                                            Id = Guid.NewGuid(),
                                            Position = short.Parse(gridSource.Count.ToString())
                                        };

                    foreach (var lookupControlId in lookupIds)
                    {
                        var propertyName = lookupControlId.Replace(lookupName + "_", "");
                        var value = ((BaseMedianamikControl)editForm.FindControl(lookupControlId)).GetValue();
                        var property = new RecordProperty
                                           {
                                               CultureName = EditionCulture.Name,
                                               NodeTypePropertyName = propertyName,
                                               Value = value
                                           };
                        newRecord.Properties.Add(property);
                    }

                    if (currentLookup.LookupPropertyName.ToLower().Equals("parentid"))
                    {
                        newRecord.ParentId = NodeId;
                    }
                    else
                    {
                        var lookupProperty = new RecordProperty
                                                 {
                                                     CultureName = EditionCulture.Name,
                                                     NodeTypePropertyName = currentLookup.LookupPropertyName,
                                                     Value = NodeId
                                                 };

                        newRecord.Properties.Add(lookupProperty);
                    }

                    gridSource.Add(newRecord);
                }
                else
                {
                    var currentRecord = gridSource.First(r => r.Id == recordId);
                    foreach (var lookupControlId in lookupIds)
                    {
                        var propertyName = lookupControlId.Replace(lookupName + "_", "");
                        currentRecord[propertyName].Value = ((BaseMedianamikControl)editForm.FindControl(lookupControlId)).GetValue();
                    }
                }
                currentLookup.DataSource = gridSource.ToArray();
                var grid = (RadGrid)Parent.FindControlR(lookupName);
                grid.DataSource = currentLookup.GetRecordsForGrid();
                grid.DataBind();
                SwitchMode(lookupName, true);
            }
        }

        void GridItemCommand(object source, GridCommandEventArgs e)
        {
            Guid nodeId;
            if (e.CommandArgument != null && StringHelper.IsGuid(e.CommandArgument.ToString(), out nodeId))
            {
                var grid = (RadGrid)source;
                var lookupName = grid.ID;

                var currentLookup = GetCurrentLookup(lookupName);
                var records = currentLookup.DataSource.ToList();
                var record = records.First(r => r.Id.Equals(nodeId));
                records.Remove(record);

                if (e.CommandName.ToUpper() == "DELETE_NODE")
                {
                    //TODO : DELETE ROW
                    //Comment recuperer le noeud qu on veut detruire ?

                    record.SynchronizeAction = SynchronizeActions.Delete;
                    currentLookup.DataSource = records.Union(new[] { record }).ToArray();
                    grid.DataSource = currentLookup.GetRecordsForGrid();
                    grid.DataBind();
                    SwitchMode(lookupName, true);
                }
                else if (e.CommandName.ToUpper() == "EDIT_NODE")
                {
                    //Comment recuperer le noeud qu on veut editer et setter les proprietes aux controles ?
                    FillEditForm(record, currentLookup);
                    SwitchMode(lookupName, false);
                }
            }
        }

        private MedianamikLookup GetCurrentLookup(string lookupName)
        {
            var medianamikLookups = Parent.FindControlsR<MedianamikLookup>();
            return medianamikLookups.First(m => m.TypeName == lookupName);
        }

        private void FillEditForm(Record record, MedianamikLookup lookup)
        {
            var editForm = GetPlaceHolder(lookup.TypeName, EditFormPlaceHolderPrefix);
            var lookupIds = LookupPropertyIds[lookup.TypeName];

            foreach (var lookupControlId in lookupIds)
            {
                var propertyName = lookupControlId.Replace(lookup.TypeName + "_", "");
                ((BaseMedianamikControl)editForm.FindControl(lookupControlId))
                    .SetValue(record[propertyName].Value);
            }

            var saveButton = (Button)editForm.FindControl(SaveButtonPrefix + lookup.TypeName);
            saveButton.CommandArgument = record.Id.GetValueOrDefault().ToString();
        }

        private PlaceHolder GetPlaceHolder(string lookupName, string placeholderPrefix)
        {
            return (PlaceHolder)Parent.FindControlR(placeholderPrefix + lookupName);
        }

        private void SwitchMode(string lookupName, bool showGrid)
        {
            var editPlaceholder = GetPlaceHolder(lookupName, EditFormPlaceHolderPrefix);
            var gridPlaceholder = GetPlaceHolder(lookupName, GridPlaceHolderPrefix);

            if (showGrid)
            {
                gridPlaceholder.Visible = true;
                editPlaceholder.Visible = false;
            }
            else
            {
                gridPlaceholder.Visible = false;
                editPlaceholder.Visible = true;
            }
        }

        private void CreateTabs(IEnumerable<string> groups)
        {
            foreach (var group in groups)
            {
                var groupName = string.IsNullOrEmpty(group) ? DefaultGroupName : group;
                var tab = new RadTab(Translator.Translate(ResourceSets.Tabs, groupName.ToLower()))
                {
                    PageViewID = String.Concat(PageViewID, "_", groupName.ToLower())
                };
                _tabStrip.Tabs.Add(tab);
                var pageView = new RadPageView
                {
                    ID = tab.PageViewID,
                    CssClass = "ContainerEditeurPage"
                };
                _multiPage.PageViews.Add(pageView);
            }
        }

        private void SetViewstate(List<NodeProperty> props,
            IEnumerable<string> groups, List<string> propertyIds, IList<string> tmp)
        {
            MedianamikControlCount = props.Count;
            //MedianamikControlTypes = props.Select(p => p.MedianamikControl.FullName).ToArray();
            MedianamikControlTypes = tmp.ToArray();
            MedianamikControlGroups = props.Select(p => p.GroupName.ToLower()).ToArray();
            GroupCount = groups.Count();
            PropertyIds = propertyIds.ToArray();
        }

        private void SetRadControls()
        {
            if (!TrySetExisitingRadControls())
            {
                SetNewRadControls();
            }

            Controls.Add(_tabStrip);
            Controls.Add(_multiPage);
        }

        private void SetNewRadControls()
        {
            _multiPage = new RadMultiPage
            {
                ID = MultiPageID,
                CssClass = "TabPage",
                SelectedIndex = 0
            };

            _tabStrip = new RadTabStrip
            {
                ID = TabStripID,
                CausesValidation = false,
                EnableEmbeddedSkins = false,
                Skin = "Medianamik",
                SelectedIndex = 0,
                ShowBaseLine = true,
                MultiPageID = _multiPage.ID
            };
        }

        private void SetupLock(bool useDataSource, Node dataSource)
        {
            Controls.Add(LockActivator);
            Controls.Add(LockRequester);

            if (useDataSource && dataSource.Status != EntityStates.New)
            {
                LockActivator.ObjectId = dataSource.ID;
            }
        }

        private void AddValidators(Control control, string validationGroup)
        {
            _valSummary = new ValidationSummary
            {
                DisplayMode = ValidationSummaryDisplayMode.BulletList,
                ShowSummary = true,
                CssClass = "ValidationSummary",
                HeaderText = Translator.Translate("Medianamik_ContentManagement",
                                                  "ValidationSummaryHeaderText"),
                ValidationGroup = validationGroup
            };

            control.Controls.Add(_valSummary);
            control.Controls.Add(new HtmlGenericControl("br"));
        }

        private bool TrySetExisitingRadControls()
        {
            if (String.IsNullOrEmpty(RadTabStripId) || String.IsNullOrEmpty(RadMultiPageId))
                return false;

            var radTabStrip = Parent.FindControlR(RadTabStripId) as RadTabStrip;
            var radMultiPage = Parent.FindControlR(RadMultiPageId) as RadMultiPage;

            if (radTabStrip == null || radMultiPage == null)
                return false;

            _tabStrip = radTabStrip;
            _multiPage = radMultiPage;

            return true;
        }

        private void UpdateNode(Control control, Node node)
        {
            if (control is MedianamikPropertyControl)
            {
                var c = (MedianamikPropertyControl)control;

                foreach (String culture in c.CultureNames)
                {
                    if (!node.Instances.Exists(culture))
                    {
                        node.AddNodeInstance(culture);
                    }

                    node.Instances[culture].Properties[c.PropertyName].SetValue(c.GetValue(culture));
                }
            }

            foreach (Control childControl in control.Controls)
            {
                UpdateNode(childControl, node);
            }
        }

        private void DisableClientSideValidation(Control control)
        {
            if (control is BaseValidator)
            {
                BaseValidator validator = (BaseValidator)control;
                validator.EnableClientScript = false;
            }

            foreach (Control childControl in control.Controls)
            {
                DisableClientSideValidation(childControl);
            }
        }

        private bool ContainsDisabledClientScriptValidator(Control control)
        {
            if (control is BaseValidator)
            {
                BaseValidator validator = (BaseValidator)control;

                if (validator.EnableClientScript == false)
                    return true;

            }

            foreach (Control childControl in control.Controls)
            {
                if (ContainsDisabledClientScriptValidator(childControl))
                    return true;
            }

            return false;
        }

        public BaseMedianamikControl FindControlByPropertyId(Guid propertyId)
        {
            return this.FindControlR(propertyId.ToString("N")) as BaseMedianamikControl;
        }

        private class Caption : Control
        {
            protected override void Render(HtmlTextWriter writer)
            {
                const string outputFormat = @"<br class=""clearer"" />
                    <p class=""Titre12pxBordure"">{0}</p>
                    <ul id=""Legende"">
                        <li class=""Picto"">
                            <img src=""/Medianamik/images/Icones/Ico_ProprieteObligatoire.png"" class=""IconeLabel"" alt="""" />&nbsp;&nbsp;{1}
                        </li>
                        <li class=""Picto"">
                            <img src=""/Medianamik/images/Icones/Ico_ProprieteNeutreLangue.png"" class=""IconeLabel"" alt="""" />&nbsp;&nbsp;{2}
                        </li>
                    </ul>
                    <br class=""clearer"" />";

                var translatedOutput = string.Format(outputFormat
                    , Translator.Translate("Medianamik_ContentManagement", "FormTemplateCaption")
                    , Translator.Translate("Medianamik_ContentManagement", "RequiredFieldCaption")
                    , Translator.Translate("Medianamik_ContentManagement", "LanguageNeutralCaption"));

                writer.Write(translatedOutput);
            }
        }
    }

    public class MedianamikFormTemplateContainer : WebControl/*Control*/, INamingContainer
    {
        public override void RenderBeginTag(HtmlTextWriter writer)
        {

        }

        public override void RenderEndTag(HtmlTextWriter writer)
        {

        }
    }
}